<#assign idColumn=table.idColumn>
$(function () {
    var Components = {
        init: function () {
            Components.searchBar.init();
            Components.dialogs.init();
            Components.forms.init();
            Components.dataTable.init();
        },
        searchBar: (function () {
            var methods = {
                init: function () {
                    methods.initEvents();
                },
                initEvents: function () {
                    var $wrapper = methods.wrapper();
                    $wrapper.on('click', '.js-button-search', methods.search);
                    $wrapper.on('click', '.js-button-reset', methods.reset);
                    $wrapper.on('click', '.js-button-more', methods.more);
                },
                search: function () {
                    Components.dataTable.render();
                },
                reset: function () {
                    methods.wrapper().find('form')[0].reset();
                },
                more: function () {
                    var $wrapper = methods.wrapper();
                    $wrapper.find('.js-more-conditions').toggle();
                    $wrapper.find('span.glyphicon').toggle();
                },
                data: function (data) {
                    var $wrapper = methods.wrapper();
                    var $form = $wrapper.find('form');
                    if (data && $.isPlainObject(data)) {
                        // load search form data
                        $form.extendLoadData(data);
                    } else {
                        // get search form data
                        var formData = {};
                        var $conditions = $('.js-search-condition')
                        $.each($conditions, function () {
                            var $this = $(this);
                            var forItems = $this.attr('for').split(',');
                            var cVal = $this.val();
                            $.each(forItems, function (idx, obj) {
                                obj = $.trim(obj);
                                var itemValue = $.trim($form.find('[name="' + obj + '"]').val());
                                if (itemValue) {
                                    cVal = cVal.replace('?' + idx, itemValue);
                                }
                            });
                            if (-1 == cVal.indexOf('?')) {
                                formData[$this.attr('property')] = cVal;
                            }
                        });
                        return formData;
                    }
                },
                wrapper: function () {
                    return $('.js-searchBar-wrapper');
                }
            };
            return methods;
        })(),
        dataTable: (function () {
            var _dataTable;
            var methods = {
                init: function () {
                    // init data table
                    var defaults = $.dataTableCommons.getDefaults();
                    var options = {
                        columns: [
                            {data: null},
                            <#list table.columnsWithoutPrimaryKey as column>
                            {data: '${column.property}'},
                            </#list>
                            {data: null}
                        ],
                        ajax: function (data, callback, settings) {
                            var pageNumber = data['start'] / data['length'];
                            var pageSize = data['length'];
                            var requestData = $.extend(true, {}, Components.searchBar.data());
                            $.ajax({
                                url: G_CONTEXT_PATH + '/${table.viewUrl}/page-by/'+pageNumber+'/'+pageSize,
                                cache: false,
                                data: requestData,
                                dataType: 'json',
                                success: function (result) {
                                    result['draw'] = data['draw'];
                                    result['recordsTotal'] = result['pageSize'];
                                    result['recordsFiltered'] = result['totalRecords'];
                                    result['data'] = result['content'];
                                    callback(result);
                                },
                                error: function (xhr, status, err) {
                                    layer.alert('操作发生异常，请联系管理员');
                                }
                            });
                        },
                        columnDefs: [{
                            targets: 0,
                            render: function (data, type, row) {
                                return methods.wrapper().find('.js-check-column').html();
                            }
                        }, {
                            targets: -1,
                            render: function (data, type, row) {
                                return methods.wrapper().find('.js-action-column').html();
                            }
                        }]
                    };
                    _dataTable = methods.wrapper().find('table').DataTable($.extend(true, {}, defaults, options));
                    // init events
                    methods.initEvents();
                    return _dataTable;
                },
                initEvents: function () {
                    var $wrapper = methods.wrapper();
                    // create
                    $wrapper.on('click', '.js-button-create', Components.dialogs.create.show);
                    // update
                    $wrapper.on('click', '.js-button-update', function () {
                        // load form data
                        var rowData = methods.dataTable().row($(this).closest('tr')).data();
                        Components.forms.update.wrapper().extendLoadData(rowData);
                        // show dialog
                        Components.dialogs.update.show();
                    });
                    // check
                    $wrapper.on('click', 'table thead th:eq(0) :checkbox', function () {
                        var checked = this.checked;
                        $wrapper.find('table tbody tr').find('td:eq(0) :checkbox').each(function () {
                            this.checked = checked;
                        });
                        // toggle class
                        $wrapper.find('table tbody tr').toggleClass('selected', checked);
                    });
                    // click
                    $wrapper.on('click', 'table tbody tr td', function () {
                        if ($(this).children().hasClass('js-no-click')) {
                            return;
                        }
                        var ck = $(this).closest('tr').find('td:first :checkbox')[0];
                        ck['checked'] = !ck['checked'];
                        $(this).closest('tr').toggleClass('selected', ck['checked']);
                    });
                    // delete
                    $wrapper.on('click', '.js-button-delete', function () {
                        // check with the selected row
                        var $checked = $wrapper.find('table tbody tr').find('td:first :checked');
                        if ($checked.length == 0) {
                            layer.msg('请选择需要删除记录');
                            return;
                        }
                        // confirm delete with the selected row
                        layer.alert('确定删除选中的记录？', function () {
                            var dataTable = methods.dataTable();
                            var ids = $.map($checked, function (ele) {
                                return dataTable.row($(ele).closest('tr')).data()['${idColumn.property}'];
                            }).join();
                            $.ajax({
                                type: 'delete',
                                url: G_CONTEXT_PATH + '/${table.viewUrl}/' + ids,
                                cache: false,
                                dataType: 'json',
                                success: function (result) {
                                    layer.closeAll();
                                    dataTable.draw();
                                },
                                error: function (xhr, status, err) {
                                    layer.alert('操作发生异常，请联系管理员');
                                }
                            });
                        });
                    });
                    // view
                    $wrapper.on('click', '.js-button-view', function () {
                        // load data
                        var rowData = methods.dataTable().row($(this).closest('tr')).data();
                        Components.forms.view.wrapper().extendLoadData(rowData);
                        // show dialog
                        Components.dialogs.view.show();
                    });
                },
                render: function () {
                    methods.dataTable().draw();
                },
                wrapper: function () {
                    return $('.js-dataTable-wrapper');
                },
                dataTable: function () {
                    return _dataTable;
                }
            };
            return methods;
        })(),
        dialogs: (function () {
            var defaults = {
                keyboard: false,
                backdrop: 'static',
                show: false
            };
            var privates = {
                onHidden: function (target) {
                    var $form = target.find('form');
                    $form.validate().resetForm();
                    var $helpBlock = $form.find('div.help-block');
                    $helpBlock.closest('.form-group').removeClass('has-error');
                    $helpBlock.remove();
                }
            };
            var methods = {
                init: function () {
                    methods.create.init();
                    methods.update.init();
                    methods.view.init();
                },
                create: (function () {
                    var methods = {
                        init: function () {
                            var $wrapper = methods.wrapper();
                            $wrapper.modal($.extend(true, {}, defaults))
                                .on('hidden.bs.modal', function (e) {
                                    privates.onHidden($wrapper);
                                });
                            methods.initEvents();
                            return $wrapper;
                        },
                        initEvents: function () {
                            var $wrapper = methods.wrapper();
                            $wrapper.on('click', '.js-button-save', Components.forms.create.submit);
                        },
                        show: function () {
                            methods.wrapper().modal('show');
                        },
                        hide: function () {
                            methods.wrapper().modal('hide');
                        },
                        wrapper: function () {
                            return $('.js-dialog-create');
                        }
                    };
                    return methods;
                })(),
                update: (function () {
                    var methods = {
                        init: function () {
                            var $wrapper = methods.wrapper();
                            $wrapper.modal($.extend(true, {}, defaults))
                                .on('hidden.bs.modal', function (e) {
                                    privates.onHidden($wrapper);
                                });
                            methods.initEvents();
                            return $wrapper;
                        },
                        initEvents: function () {
                            var $wrapper = methods.wrapper();
                            $wrapper.on('click', '.js-button-save', Components.forms.update.submit);
                        },
                        show: function () {
                            methods.wrapper().modal('show');
                        },
                        hide: function () {
                            methods.wrapper().modal('hide');
                        },
                        wrapper: function () {
                            return $('.js-dialog-update');
                        }
                    };
                    return methods;
                })(),
                view: (function () {
                    var methods = {
                        init: function () {
                            var $wrapper = methods.wrapper();
                            $wrapper.modal($.extend(true, {}, defaults))
                                .on('hidden.bs.modal', function (e) {
                                    $wrapper.find('form')[0].reset();
                                });
                            return $wrapper;
                        },
                        show: function () {
                            methods.wrapper().modal('show');
                        },
                        hide: function () {
                            methods.wrapper().modal('hide');
                        },
                        wrapper: function () {
                            return $('.js-dialog-view');
                        }
                    };
                    return methods;
                })()
            };
            return methods;
        })(),
        forms: (function () {
            var validateDefaults = $.validateCommons.getDefaults();
            var ajaxDefaults = {
                success: function (result, status, xhr) {
                    // close dialog
                    Components.dialogs.create.hide();
                    Components.dialogs.update.hide();
                    // refresh data table
                    Components.dataTable.render();
                },
                error: function (xhr, status, err) {
                    layer.alert('服务器出现异常，请联系管理员');
                }
            };
            var methods = {
                init: function () {
                    methods.create.init();
                    methods.update.init();
                    methods.view.init();
                },
                create: (function () {
                    var methods = {
                        init: function () {
                            var $wrapper = methods.wrapper();
                            $wrapper.validate($.extend(true, {}, validateDefaults));
                            return $wrapper;
                        },
                        submit: function () {
                            var $wrapper = methods.wrapper();
                            var ajaxOptions = $wrapper.extendAjaxOptions();
                            var merged = $.extend(true, {}, ajaxDefaults, ajaxOptions, {
                                beforeSend: function (xhr) {
                                    return $wrapper.valid();
                                }
                            });
                            $.ajax(merged);
                        },
                        wrapper: function () {
                            return Components.dialogs.create.wrapper().find('form');
                        }
                    };
                    return methods;
                })(),
                update: (function () {
                    var methods = {
                        init: function () {
                            var $wrapper = methods.wrapper();
                            $wrapper.validate($.extend(true, {}, validateDefaults));
                            return $wrapper;
                        },
                        submit: function () {
                            var $wrapper = methods.wrapper();
                            var ajaxOptions = $wrapper.extendAjaxOptions();
                            var merged = $.extend(true, {}, ajaxDefaults, ajaxOptions, {
                                beforeSend: function (xhr) {
                                    return $wrapper.valid();
                                }
                            });
                            $.ajax(merged);
                        },
                        wrapper: function () {
                            return Components.dialogs.update.wrapper().find('form');
                        }
                    };
                    return methods;
                })(),
                view: (function () {
                    var methods = {
                        init: function () {
                            return methods.wrapper();
                        },
                        wrapper: function () {
                            return Components.dialogs.view.wrapper().find('form');
                        }
                    };
                    return methods;
                })()
            };
            return methods;
        })()
    };
    Components.init();
});